home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / lib / table / dm_table.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  12.9 KB  |  436 lines

  1. /*
  2.  *     MULTI-CHANNEL MEMO DISTRIBUTION FACILITY  (MMDF)
  3.  *
  4.  *
  5.  *     Copyright (C) 1979,1980,1981  University of Delaware
  6.  *
  7.  *     Department of Electrical Engineering
  8.  *     University of Delaware
  9.  *     Newark, Delaware  19711
  10.  *
  11.  *     Phone:  (302) 738-1163
  12.  *
  13.  *
  14.  *     This program module was developed as part of the University
  15.  *     of Delaware's Multi-Channel Memo Distribution Facility (MMDF).
  16.  *
  17.  *     Acquisition, use, and distribution of this module and its listings
  18.  *     are subject restricted to the terms of a license agreement.
  19.  *     Documents describing systems using this module must cite its source.
  20.  *
  21.  *     The above statements must be retained with all copies of this
  22.  *     program and may not be removed without the consent of the
  23.  *     University of Delaware.
  24.  *
  25.  *
  26.  *     version  -1    David H. Crocker    March   1979
  27.  *     version   0    David H. Crocker    April   1980
  28.  *     version  v7    David H. Crocker    May     1981
  29.  *     version   1    David H. Crocker    October 1981
  30.  *
  31.  */
  32.  
  33. #include "util.h"
  34. #include "mmdf.h"
  35. #include "ch.h"                   /* has table state strcture def       */
  36. #include "dm.h"
  37. #include "chdbm.h"
  38.  
  39. extern Domain **dm_list;
  40. extern Domain *dm_s2dom();
  41. extern struct ll_struct   *logptr;
  42. extern char *strcpy ();
  43. extern char *index();
  44. extern char *rindex();
  45.  
  46. /*
  47.  * when mangling addresses, should we try the reverse before or after
  48.  * the RFC822 direction
  49.  * is set by submit otherwise is as below.
  50.  */
  51.  
  52. typedef struct {char *dptr; int dsize;} datum;
  53.  
  54.  
  55. /*
  56.  * Steve Kille   jan 84   Redo this module
  57.  *
  58.  * G. Brendan Reilly May 84     take out dependencies on DBM package
  59.  *
  60.  *
  61.  */
  62.  
  63.  
  64. /* *******  FIND VALUE (address), GIVEN ITS KEY (hostname)  ********* */
  65.  
  66.  
  67. LOCFUN
  68. dm_k2val (dmntbl, subdmn, domain, dmnroute)
  69.                    /* sub-domain spec -> routing host   */
  70. register Domain  *dmntbl;         /* domain table to look in            */
  71. register char  *subdmn;          /* name of sub-domain to look for     */
  72. char *domain;                   /* where to stuff full domain name      */
  73. Dmn_route *dmnroute;              /* where to put routing information   */
  74. {
  75.     char *p;
  76.     int retval;
  77.     char sdbuf[LINESIZE];
  78.     
  79.  
  80. #ifdef DEBUG
  81.     ll_log (logptr, LLOGBTR, "dm_k2val (%s, %s)", dmntbl -> dm_name, subdmn);
  82. #endif
  83.  
  84.     if (((dmntbl->dm_table->tb_flags & TB_SRC) == TB_NS) &&
  85.     isstr(dmntbl->dm_domain)) {
  86.     sprintf(sdbuf, "%s.%s", subdmn, dmntbl->dm_domain);
  87.     retval = tb_k2val (dmntbl->dm_table, TRUE, sdbuf, dmnroute->dm_buf);
  88.     }  
  89.     else
  90.     retval = tb_k2val (dmntbl->dm_table, TRUE, subdmn, dmnroute->dm_buf);
  91.  
  92.     switch(retval) {
  93.     case MAYBE:
  94.     return(MAYBE);
  95.     case OK:
  96. #ifdef DEBUG
  97.     ll_log (logptr, LLOGFTR, "dm_k2val: hit with '%s'", dmnroute->dm_buf);
  98. #endif
  99.     dmnroute -> dm_argc = str2arg (dmnroute -> dm_buf,
  100.             DM_NFIELD, dmnroute -> dm_argv, (char *)0);
  101.     (void) strcpy(domain, dmnroute -> dm_argv[0]);
  102.     return (OK);
  103.     }
  104.  
  105.     /* Not found yet--give up if we're not allowed to look for subdomains
  106.        to route via */
  107.     if ((dmntbl->dm_table->tb_flags & TB_ROUTE) != TB_ROUTE)
  108.     return(NOTOK);
  109.  
  110.     /* Here we're going to look for successive subdomains (b.c.d, c.d, d)
  111.        on the chance that we can route via that subdomain to reach a.b.c.d.
  112.        For example, given oxnard.bitnet, we'll look for a table entry such
  113.        as "bitnet:cunyvm.cuny.edu" where cunyvm.cuny.edu is the route to
  114.        *.bitnet */
  115.  
  116.     p = subdmn;
  117.     while ((p = index (p, '.')) != (char *)0)
  118.     {
  119.     char tdmnbuf[LINESIZE];
  120.  
  121.     p++;
  122.     if (((dmntbl->dm_table->tb_flags & TB_SRC) == TB_NS) &&
  123.         isstr(dmntbl->dm_domain)) {
  124.         sprintf(sdbuf, "%s.%s", p, dmntbl->dm_domain);
  125.         retval = tb_k2val (dmntbl->dm_table, TRUE, sdbuf, tdmnbuf);
  126.     }  
  127.     else
  128.         retval = tb_k2val (dmntbl->dm_table, TRUE, p, tdmnbuf);
  129.  
  130.     switch(retval) {
  131.     case MAYBE:
  132.         return(MAYBE);
  133.     default:
  134.         continue;
  135.     case OK:
  136.         break;
  137.     }
  138.                     /* get the entry */
  139. #ifdef DEBUG
  140.     ll_log (logptr, LLOGFTR, "dm_k2val: hit with '%s' for '%s.%s'",
  141.         tdmnbuf, p, dmntbl->dm_domain);
  142. #endif
  143.     *(p - 1) = '\0';            /* build the domain */
  144.     if (!isstr(dmntbl->dm_domain)) {
  145.         if (*p == '\0')
  146.         (void) strcpy (domain, subdmn);
  147.         else
  148.         sprintf (domain, "%s.%s", subdmn, p);
  149.     }
  150.     else
  151.         sprintf (domain, "%s.%s.%s", subdmn, p, dmntbl -> dm_domain);
  152.  
  153.     sprintf (dmnroute -> dm_buf, "%s %s", domain, tdmnbuf);
  154.     dmnroute -> dm_argc = str2arg (dmnroute -> dm_buf,
  155.             DM_NFIELD, dmnroute -> dm_argv, (char *)0);
  156.     return (OK);
  157.     }
  158.  
  159.     return (NOTOK);
  160. }
  161.  
  162. /*  ***********  GIVEN Subdomain, FIND HOST ROUTE  ************* */
  163. /*
  164.  * If BOTHEND is defined then we are almost certainly running in JNT
  165.  * land and so we should try the reversed address before the RFC822
  166.  * direction, should save some cpu cycles
  167.  */
  168.  
  169. LOCFUN
  170. Domain *
  171. #ifndef BOTHEND
  172.     dm_sd2route (value, domain, dmnroute)
  173.     char *value;                /* what the use provides                */
  174.     char *domain;               /* full domain value                    */
  175.     Dmn_route *dmnroute;        /* source route                         */
  176. #else
  177.     dm_sd2route (value, reverse, domain, dmnroute)
  178.     char *value;                /* what the use provides                */
  179.     char *reverse;              /* the same bacwards                    */
  180.     char *domain;               /* full domain value                    */
  181.     Dmn_route *dmnroute;        /* source route                         */
  182. #endif
  183. {
  184.     char *sdptr;
  185.     Domain *dmnptr;
  186.     char official[LINESIZE];
  187. #ifdef BOTHEND
  188.     char *revsdptr = reverse;
  189. #endif
  190. #ifdef DEBUG
  191.     ll_log (logptr, LLOGBTR, "dm_sd2route (%s)", seenull(value));
  192. #endif
  193.                     /* first try the JNT way round if */
  194.                     /* got BOTHEND defined */
  195. #ifdef    BOTHEND
  196.     if ((dmnptr = dm_s2dom (reverse, official, dmnroute -> dm_buf)) !=
  197. (Domain *) NOTOK || (dmnptr = dm_s2dom (value, official, dmnroute -> dm_buf))
  198.     != (Domain *) NOTOK)
  199. #else
  200.     if ((dmnptr = dm_s2dom (value, official, dmnroute -> dm_buf))
  201.     != (Domain *) NOTOK)
  202. #endif
  203.     {
  204.     if(dmnptr == (Domain *)MAYBE)
  205.         return(dmnptr);
  206.     (void) strcpy(domain, official);
  207.     dmnroute -> dm_argc = str2arg (dmnroute -> dm_buf, DM_NFIELD,
  208.         dmnroute -> dm_argv, (char *)0);
  209. #ifdef DEBUG
  210.     ll_log (logptr, LLOGFTR, "dm_sd2route: Domain value '%s' from '%s'",
  211.         domain, dmnptr -> dm_show);
  212. #endif
  213.     return (dmnptr);
  214.     }
  215.  
  216.     /*
  217.      *  If not, move in from left.  Progressing on both forwards
  218.      *  and backwards options.
  219.      */
  220.     sdptr = value;
  221.     while ((sdptr = index (sdptr, '.')) != (char *) 0)
  222.     {
  223.     char tbuf[LINESIZE];
  224.  
  225. #ifdef  BOTHEND
  226.     revsdptr = index (revsdptr, '.') + 1;
  227.     if ((dmnptr = dm_s2dom (revsdptr, official, tbuf)) != (Domain *) NOTOK)
  228.     {
  229.         if(dmnptr == (Domain *)MAYBE)
  230.         return(dmnptr);
  231.         *(revsdptr - 1) = '\0';
  232.         sprintf (domain, "%s.%s", reverse, official);
  233.         sprintf (dmnroute -> dm_buf, "%s %s", domain, tbuf);
  234.         dmnroute -> dm_argc = str2arg (dmnroute -> dm_buf, DM_NFIELD,
  235.         dmnroute -> dm_argv, (char *)0);
  236. #ifdef DEBUG
  237.         ll_log(logptr,LLOGFTR, "Domain value (rev) '%s' from '%s',o = '%s'",
  238.         domain, dmnptr -> dm_show, official);
  239. #endif
  240.         return (dmnptr);
  241.     }
  242. #endif /* BOTHEND */
  243.  
  244.     if ((dmnptr = dm_s2dom (++sdptr, official, tbuf)) != (Domain *) NOTOK)
  245.     {
  246.         if(dmnptr == (Domain *)MAYBE)
  247.         return(dmnptr);
  248.         *(sdptr - 1) = '\0';
  249.         sprintf (domain, "%s.%s",  value, official);
  250.         sprintf (dmnroute -> dm_buf, "%s %s", domain, tbuf);
  251.         dmnroute -> dm_argc = str2arg (dmnroute -> dm_buf, DM_NFIELD,
  252.         dmnroute -> dm_argv, (char *)0);
  253. #ifdef DEBUG
  254.         ll_log (logptr, LLOGFTR, "Domain value '%s' from '%s', o = '%s'",
  255.         domain, dmnptr -> dm_show, official);
  256. #endif
  257.         return (dmnptr);
  258.     }
  259.     }
  260.  
  261. #ifdef DEBUG
  262.     ll_log (logptr, LLOGBTR, "'%s' not found", value);
  263. #endif
  264.     return ((Domain *) NOTOK);
  265. }
  266.  
  267. /*  ***********  GIVEN VALUE, FIND HOST ROUTE  ******************** */
  268.  
  269. /* This will take any value, and map it into a domain route.            */
  270. /* It is optimised for val being a fully qualified domain               */
  271.  
  272. #ifndef BOTHEND
  273.  
  274. Domain *
  275.     dm_v2route (value, domain, dmnroute)
  276.     char *value;                /* what the use provides                */
  277.     char *domain;               /* full domain value                    */
  278.     register Dmn_route *dmnroute;        /* source route                */
  279. {
  280.     Dmn_route tmpdmn;           /* hold parsed domain string            */
  281.     register Domain *dmnptr;
  282.     Domain **seed;
  283.     int sublen;                 /* length of right-hand to look up      */
  284.     int ind;
  285.     int perhaps = 0;
  286.  
  287. #ifdef DEBUG
  288.     ll_log (logptr, LLOGBTR, "dm_v2route (%s)", seenull(value));
  289. #endif
  290.     if (value != (char *) 0)
  291.         (void) strcpy (tmpdmn.dm_buf, value);
  292.     else
  293.         *tmpdmn.dm_buf = '\0';
  294.     tmpdmn.dm_argc = cstr2arg (tmpdmn.dm_buf, DM_NFIELD, tmpdmn.dm_argv, '.');
  295.     if (tmpdmn.dm_argc == NOTOK) {
  296. #ifdef  DEBUG
  297.     ll_log (logptr, LLOGTMP, "Cstr2arg failed (%s)", tmpdmn.dm_buf);
  298. #endif
  299.     return ( (Domain *)NOTOK);
  300.     }
  301.  
  302. #ifdef DEBUG
  303.     ll_log (logptr, LLOGFTR, "%d fields", tmpdmn.dm_argc);
  304. #endif
  305.  
  306.     dmnroute -> dm_argc = 1;    /* initialize with something safe */
  307.     (void) strcpy (dmnroute -> dm_buf, value);
  308.     dmnroute -> dm_argv[0] = dmnroute -> dm_buf;
  309.  
  310.     tmpdmn.dm_argc--;
  311.  
  312.     for (ind = sublen = 0; ind <= tmpdmn.dm_argc; ind++)
  313.     {
  314.     if (ind != 0)
  315.         tmpdmn.dm_buf[sublen - 1] = '.';
  316.                 /* undo cstr2arg!                       */
  317.     sublen += strlen (tmpdmn.dm_argv[ind]);
  318.                 /* how much to peel off, from right     */
  319.                 /* the +1 is for the delimiter          */
  320.     if (ind != tmpdmn.dm_argc)
  321.         sublen++;       /* point to next if not last            */
  322.     seed = (Domain **) 0;
  323.     while ((dmnptr=dm_nm2struct(&value[sublen],&seed)) != (Domain *) NOTOK)
  324.     {
  325.         switch(dm_k2val (dmnptr, tmpdmn.dm_argv[0], domain, dmnroute)){
  326.         case MAYBE:
  327.             if ((dmnptr->dm_table->tb_flags & TB_ABORT) == TB_ABORT)
  328.             return((Domain *) MAYBE);
  329.         perhaps++;
  330.         continue;       /* keep trying other domain entries */
  331.         case OK:
  332. #ifdef DEBUG
  333.         ll_log (logptr, LLOGFTR,
  334.             "%s' hit in domain table '%s' with '%s'",
  335.             value, dmnptr -> dm_show, dmnroute -> dm_buf);
  336. #endif
  337.         return (dmnptr);
  338.         }
  339.     }
  340.     }
  341.     return (perhaps? (Domain *) MAYBE : dm_sd2route (value, domain, dmnroute));
  342. }
  343.  
  344. #else /* BOTHEND */
  345.  
  346. LOCFUN Domain *
  347. dm_rv2route (value, domain, dmnroute)
  348.     char *value;                /* what the use provides                */
  349.     char *domain;               /* full domain value                    */
  350.     register Dmn_route *dmnroute;        /* source route                */
  351. {
  352.     Dmn_route tmpdmn;           /* hold parsed domain string            */
  353.     register Domain *dmnptr;
  354.     int sublen;                 /* length of right-hand to look up      */
  355.     int ind;
  356.     char buf[LINESIZE];
  357.     Domain **seed;
  358.     int perhaps = 0;
  359.  
  360.     (void) strcpy (tmpdmn.dm_buf, value);
  361.     tmpdmn.dm_argc = cstr2arg (tmpdmn.dm_buf, DM_NFIELD, tmpdmn.dm_argv, '.');
  362.     if (tmpdmn.dm_argc == NOTOK) {
  363. #ifdef  DEBUG
  364.     ll_log (logptr, LLOGTMP, "Cstr2arg failed (%s)", tmpdmn.dm_buf);
  365. #endif
  366.     return ( (Domain *)NOTOK);
  367.     }
  368.  
  369. #ifdef DEBUG
  370.     ll_log (logptr, LLOGFTR, "%d fields", tmpdmn.dm_argc);
  371. #endif
  372.  
  373.     tmpdmn.dm_argc--;
  374.     for (ind = sublen = 0; ind <= tmpdmn.dm_argc; ind++)
  375.     {
  376.     if (ind != 0)
  377.         tmpdmn.dm_buf[sublen - 1] = '.';
  378.                 /* undo cstr2arg!                       */
  379.     sublen += strlen (tmpdmn.dm_argv[ind]);
  380.                 /* how much to peel off, from right     */
  381.                 /* the +1 is for the delimiter          */
  382.     if (ind != tmpdmn.dm_argc)
  383.         sublen++;       /* point to next if not last            */
  384.     seed = (Domain **) 0;
  385.     while ((dmnptr=dm_nm2struct(&value[sublen],&seed)) != (Domain *) NOTOK)
  386.     {
  387.         switch(dm_k2val (dmnptr, tmpdmn.dm_argv[0], domain, dmnroute)){
  388.         case MAYBE:
  389.             if ((dmnptr->dm_table->tb_flags & TB_ABORT) == TB_ABORT)
  390.             return((Domain *) MAYBE);
  391.         perhaps++;
  392.         continue;       /* keep trying other domain entries */
  393.         case OK:
  394. #ifdef DEBUG
  395.         ll_log (logptr, LLOGFTR,
  396.             "%s' hit in domain table '%s' with '%s'",
  397.             value, dmnptr -> dm_show, dmnroute -> dm_buf);
  398. #endif
  399.         return (dmnptr);
  400.         }
  401.     }
  402.     }
  403.     return (perhaps? (Domain *) MAYBE : (Domain *) 0);     /* not found */
  404. }
  405.  
  406. Domain *
  407.     dm_v2route (value, domain, dmnroute)
  408.     char *value;                /* what the use provides                */
  409.     char *domain;               /* full domain value                    */
  410.     Dmn_route *dmnroute;        /* source route                         */
  411. {
  412.     Domain *dmnptr;
  413.     char *reverse;              /* to handle bigend mess                */
  414.     extern char *ap_dmflip();
  415.  
  416.     if (value == (char *) 0) value = "";
  417. #ifdef DEBUG
  418.     ll_log (logptr, LLOGBTR, "dm_v2route (%s)", value);
  419. #endif
  420.     dmnroute -> dm_argc = 1;    /* initialize with something safe */
  421.     (void) strcpy (dmnroute -> dm_buf, value);
  422.     dmnroute -> dm_argv[0] = dmnroute -> dm_buf;
  423.  
  424.     if ((dmnptr = dm_rv2route (value, domain, dmnroute)) != (Domain *)0)
  425.     return (dmnptr);
  426.     reverse = ap_dmflip (value);
  427.     if( (dmnptr = dm_rv2route (reverse, domain, dmnroute)) != (Domain *)0){
  428.     free (reverse);
  429.     return (dmnptr);
  430.     }
  431.     dmnptr = dm_sd2route (value, reverse, domain, dmnroute);
  432.     free (reverse);
  433.     return (dmnptr);
  434. }
  435. #endif /* BOTHEND */
  436.